#!/usr/bin/env python3
import pika
import time
import os
import json
from subprocess import Popen, PIPE
import sqlite3
import sys
import getUrlfile

def sendReloadDbMsg(channel):
    commandmsg = 'reload db'
    channel.basic_publish(exchange='',
                          routing_key='DbReloadQueue',
                          body=commandmsg)
    print("msg: ", commandmsg)
    print(" [x] Sent msg out!")


def callback_getcommand(ch, method, properties, body):
    '''
    input: message from passDB manager
    output: message to DBImgQueue
    '''
    errcode = 0
    print(" [x] Received %r" % body)
    msg = str(body, 'utf-8')

    msgdict = json.loads(msg)
    operate = msgdict.get("operate")
    url = msgdict.get("url")
    faceid = msgdict.get("faceid")

    if operate == "face_add": 
        localtmpjpgpath = "../EP_imgTmpSpace/" + str(time.time()) + ".jpg"
        try:
            getUrlfile.requestImg(url, localtmpjpgpath)
        except:
            errcode = 1
            print(url, " resource can't be download. err!")
            ch.basic_ack(delivery_tag = method.delivery_tag)

        if not os.path.exists(localtmpjpgpath):
            errcode = 1
        
        if errcode == 0:
            imgspathlist = []
            faceidlist = []
            optionlist = []
            for i in range(1):
                imgspathlist.append(localtmpjpgpath)
                faceidlist.append(faceid)
                optionlist.append(operate)

            # 生成img to face feature vector调用指令消息内容,发布消息
            dict = {}
            dict.update({'list_imgspath':imgspathlist})
            dict.update({'list_faceids':faceidlist})
            dict.update({'list_options':optionlist})
            commandmsg = json.dumps(dict)

            ch.basic_publish(exchange='',
                                  routing_key='DbImgpathQueue',
                                  body=commandmsg)
            print("msg: ", commandmsg)
            print(" [x] Sent msg out!")

            ch.basic_ack(delivery_tag = method.delivery_tag)
    elif operate == "face_del": # notice: this del a person's all photos 
        faceidlist = []
        optionlist = []
        featurelist = [[[]]]
        faceidlist.append(faceid)
        optionlist.append(operate)
        dict = {}
        dict.update({'list_faceids':faceidlist})
        dict.update({'list_options':optionlist})
        dict.update({'list_facesfeaturevecs':featurelist})
        commandmsg = json.dumps(dict)

        ch.basic_publish(exchange='',
                              routing_key='DbVecQueue',
                              body=commandmsg)
        print("msg: ", commandmsg)
        print(" [x] Sent msg out!")

        ch.basic_ack(delivery_tag = method.delivery_tag)
    else:
        print("db operate command format err.")
        ch.basic_ack(delivery_tag = method.delivery_tag)


def callback_operatedb(ch, method, properties, body):
    '''
    input: face feature vector
    output: insert face feature vector to db
    '''
    start = time.time()
    print(" [x] Received %r" % body)
    msg = str(body, 'utf-8')
    dict = json.loads(msg)
    list_faceids = dict["list_faceids"]
    list_options = dict["list_options"]
    list_facesfeaturevecs = dict["list_facesfeaturevecs"]

    con = sqlite3.connect("../EP_faceDB/faceiddatabase.db3")
    cur = con.cursor()
    try:
        cur.execute('CREATE TABLE facedb(face_id TEXT, face_featurevector TEXT PRIMARY KEY)')
        con.commit()
    except:
        print("db is already exists.")

    ifdbchanged = 0 
    for i in range(1):
        facenum = len(list_facesfeaturevecs[i])
        for j in range(facenum):
            curfaceid = str(list_faceids[i])
            curfacevec = str(list_facesfeaturevecs[i][j])
            curoption = str(list_options[i])

            # add face
            if curoption == "face_add":
                try:
                    cur.execute("INSERT INTO facedb(face_id, face_featurevector) VALUES('%s', '%s')" % (curfaceid, curfacevec))
                    con.commit()
                    ifdbchanged = 1
                except:
                    print("current face vector is already exists.")

            # del face
            #if "face" in curoption and "del" in curoption:
            #    try:
            #        cur.execute("DELETE FROM facedb WHERE face_featurevector = '%s'" % curfacevec)
            #        con.commit()
            #        ifdbchanged = 1
            #    except:
            #        print("current face vector is not found.")

            # del all faces of a person
            if curoption == "face_del":
                try:
                    cur.execute("DELETE FROM facedb WHERE face_id = '%s'" % curfaceid)
                    con.commit()
                    ifdbchanged = 1
                except:
                    print("current person/faceid is not found.")
    con.close()

    # if face db changed, face recognition module should reload db
    if ifdbchanged:
        commandmsg = "reload face db"
        ch.basic_publish(exchange='',
                              routing_key='DbReloadQueue',
                              body=commandmsg)
        print("msg: ", commandmsg)
        print(" [x] Sent msg out!")

    ch.basic_ack(delivery_tag = method.delivery_tag)
    end = time.time()
    print("time cost: ", end - start)


if __name__ == '__main__':
    '''
    发布img imgpath指令至rabbitMQ服务器
    '''
    # 建立连接
    credentials = pika.PlainCredentials('aiot', 'aiot')
    Parameter = pika.ConnectionParameters('127.0.0.1', 5672, '/', credentials)
    connection = pika.BlockingConnection(Parameter)
    channel = connection.channel()

    # 声明/指定消息队列
    channel.queue_declare(queue='DbImgpathQueue')
    channel.queue_declare(queue='DbVecQueue')
    channel.queue_declare(queue='DbReloadQueue')
    channel.queue_declare(queue='PDMoutQueue')
    #channel.exchange_declare(exchange='PDMoutTopic', exchange_type='topic')
    #randqueue = channel.queue_declare('', exclusive=True)
    #routing_key = sys.argv[1] if len(sys.argv) > 1 else '111.111.111'
    #queue_name = randqueue.method.queue
    #channel.queue_bind(exchange='PDMoutTopic', queue=queue_name, routing_key=routing_key)

    # 配置从rabbitMQ服务器消息队列中取消息的参数
    channel.basic_consume(queue='PDMoutQueue', on_message_callback=callback_getcommand)
    channel.basic_consume(queue='DbVecQueue', on_message_callback=callback_operatedb)

    # 断开连接
    #connection.close()

    # 永久持续运行
    print(' [*] Waiting for messages. To exit press CTRL+C')
    channel.start_consuming()

